﻿
#ifndef	CLIENT_SOCKET_MGR_H
#define  CLIENT_SOCKET_MGR_H

#include "MemBlockPool2.h"
#include "ClientSocket.h"
#include "ILogic.h"
#include "IDataRepository.h"
#include "IEventBridge.h"

class GnsClientFrame 
{
public:

	enum
	{
		CSH_ERR_WSASocket_FAIL = 10,
		CSH_ERR_is_invalid = 15,		// 无效对端
		CSH_ERR_ClientSocket_invalid = 20,	// 客户端下标值越界
		CSH_ERR_IS_INVALID_SOCKET = 30,
		CSH_ERR_CLOSE_SOCKET_FAIL = 40,
		CSH_ERR_m_pTimeQueue_is_0 = 50,
		CSH_ERR_m_hTimer_is_0 = 60,
		CSH_ERR_CreateTimerQueueTimer = 70,
		CSH_ERR_DeleteTimerQueueTimer = 80,
		CSH_ERR_CMemBlock_is_0 = 90,
		CSH_ERR_OVER_SEND_HI_WATER_MARK = 100,	// m_deqSend 超出上水位标啦
		CSH_ERR_WSASocket_fail = 110,
	};

	enum 
	{
		MAX_CLIENT_NUM = 5,		// 客户端的最大数量
	};

public:
	GnsClientFrame();
	~GnsClientFrame();

	static	GnsClientFrame* getInstance();
	static void destoryInstance();

private:
	static	GnsClientFrame* create();

public:
	virtual bool init();

	ClientSocket*  registClient(int iClientId, const char* szServerIp, int iPort, int iMsgBlockSize = 2048, int bManualConnect = 1);

	// 手动连接
	int  manualConnect(int iClientId);

	// 客户端 Socket 有效
	bool  isClientSocketValid(int iClientId);

	// 启动
	int start();

	// 获得两个数里的最小数
	static int min2(int a, int b);

	int closeSocket(int	iClientId);

	// 发送数据
	int sendMsg(int	iClientId,  int iMainCode, int iSubCode, char* pData, int iDataLen, char* szFunName = nullptr);

	// 设置内存块的参数
	void setMemBlock(	int iMsgBlockSize = CMemBlockPool2::DEF_MEMBLOCK_SIZE, 
										int nInitElementCount = CMemBlockPool2::DEF_INIT_COUNT,
										int nMaxElementCount = CMemBlockPool2::DEF_MAX_COUNT);

	// 设置逻辑模块
	void setLogic(ILogic* pLogic);

	// 设置数据区模块
	void setDataRepository(IDataRepository* pDataRepository);

	// 模拟框架功能的定时器
	void timerFrameFun();

	// 根据客户端参数类型获得客户端参数值
	// 成功返回正数值，失败返回 -1
	int getParamByType(int iClientId, CLIENT_PARAM_TYPE cpt);

private:

	// 停止
	int stop();

private:
	static GnsClientFrame*  _pGnsClientFrame;

public:
	std::vector<ClientSocket*>	_vecClientSocket;
	//std::vector<ClientSocket::INTERIOR_INFO>	_vecInteriorInfo;

public:

	CMemBlockPool2* _pMsgPool = nullptr;			// 消息池
	ILogic*					_pLogic = nullptr;				// 逻辑模块
	IDataRepository*				_pDataRepository = nullptr;			// 数据区

	int _msgBlockSize = CMemBlockPool2::DEF_MEMBLOCK_SIZE;		//  CMemBlock2 消息块的尺寸
	int _initElementCount = CMemBlockPool2::DEF_INIT_COUNT;			//  池内元素的初始数量
	int _maxElementCount = CMemBlockPool2::DEF_MAX_COUNT;		//  池内元素的最大数量

	std::thread			_frameFunThread;			// 框架功能线程
	std::mutex			_mutexFrameFun;			// 非递归互斥，针对 _dequeCoreMsg

	std::atomic<bool>		m_bStart;				// 已经开始了，ture 表示 start 状态， false 表示 stop 状态
};

#endif
